package com.platform.os.util;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

/**
 * @author KangJun 2007-10-07.
 */
@SuppressWarnings("unchecked")
public class FileUpload {
	//String fullfileName;	全文件名
	//String fileName;		不带扩展名的文件名
	//String fileExtend;	文件扩展名
	//String path;			系统路径
	//String urlPath;		以项目根目录为起点的路径
	//String filePath;		path + fullfileName
	//String urlFilePath;	urlPath + fullfileName

	/** 上传文件，存放到指定目录的指定文件名.
	 * @param request 上传请求数据流
	 * @param urlPath 文件存放目录，相对应用部署目录，如：/image/ad
	 * @param fileName	文件名，不带类型后缀，fileName为空表示用客户端文件名
	 * @flag 1-如果有同名文件存在则不上传，2-如果有同名文件存在则替换，3-如果有同名文件存在则生成其他文件名
	 * @return String 文件名，带文件类型后缀 null表示失败
	 */
	public static String save(HttpServletRequest request, String urlPath, String fileName, int flag) {
		ServletInputStream servletInputStream;
		try {
			servletInputStream = request.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		int formSize = request.getContentLength();

		DataInputStream dataInputStream = new DataInputStream(servletInputStream);
		byte[] b = new byte[formSize];
		byte t = 0;
		int i = 0;
		while (true) {
			try {
				t = dataInputStream.readByte();
			} catch (IOException e) {
				break;
			}
			b[i] = t;
			i++;
		}

		String stringData = "";

		//取客户端文件名
		try {
			stringData = new String(b, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		int start = stringData.indexOf("filename=\"");
		String tempStr = stringData.substring(start + 10);
		start = tempStr.indexOf("\"");
		tempStr = tempStr.substring(0, start);
		start = tempStr.lastIndexOf("\\");
		//客户端全文件名
		String cFullfileName = tempStr.substring(start + 1).toLowerCase();
		String cFileName = FileInfo.getFileName(cFullfileName);
		String cFileExtend = FileInfo.getFileExtend(cFullfileName);
		//服务器文件名
		String sFullFileName;
		String sFileName;
		if (fileName == null) {
			sFullFileName = cFullfileName;
			sFileName = cFileName;
		} else {
			sFileName = fileName;
			sFullFileName = FileInfo.getFullFileName(sFileName, cFileExtend);
		}
		String filePath = FileInfo.getFilePath(urlPath, sFullFileName);
		File file = new File(filePath);
		if (file.exists()) {
			if (flag == 1) {
				return sFullFileName;
			}
			if (flag == 2) {
				file.delete();
			}
			if (flag == 3) {
				//生成新文件名
				sFullFileName = FileInfo.getIncrementFileName(urlPath, sFullFileName);
				filePath = FileInfo.getFilePath(urlPath, sFullFileName);
				file = new File(filePath);
			}
		}

		//创建文件
		FileOutputStream fileOutputStream = null;
		try {
			file.getParentFile().mkdirs();
			file.createNewFile();
			fileOutputStream = new FileOutputStream(file);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

		try {
			stringData = new String(b, "ISO8859_1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}

		start = stringData.indexOf("Content-Type:");
		String fileData = stringData.substring(start);
		start = fileData.indexOf("\n");
		fileData  = fileData.substring(start + 3);
		start = fileData.indexOf("\n-----------------------------");
		if (start != -1) {
			fileData  = fileData.substring(0, start - 1);
		}

		try {
			byte[] img = fileData.getBytes("ISO8859_1");
			for (i = 0; i < img.length; i++) {
				fileOutputStream.write(img[i]);
			}
			fileOutputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

		return sFullFileName;
	}

	/** 上传文件，存放到配置文件中文件上传临时目录.可上传多个文件
	 * 返回HashMap.
	 * 获得parameter值的方式为 HashMap map.get("parameterName").
	 * 如：String name = map.get("name").
	 * 如：String file1 = map.get("file1").
	 * 客户端文件后缀名保存不变.文件名增加sessionId以防止冲突。
	 * 如果有上传文件，则文件名转存为 url文件名。如：/upfile/2213A0B1C0ECEEA18467A8B0D7A6DDA0worldhost.jpg.
	 * 接收到的文件需要转换文件名及转存到适合的目录中。
	 * @param request
	 * @return
	 */
	public static HashMap save(HttpServletRequest request) {
		String commonUpfilePath = Configure.getKeyValue("parameter.commonUpfilePath");
		if (commonUpfilePath == null || commonUpfilePath.equals("")) {
			commonUpfilePath = "/upfile";
		}
		String sessionId = request.getRequestedSessionId();
		HashMap<String, String> map = new HashMap<String, String>();
		String parameterSign = "Content-Disposition: form-data; name=\"";
		String fileSign = "filename=\"";
		List<Object[]> list = new ArrayList<Object[]>();

		ServletInputStream servletInputStream;
		try {
			servletInputStream = request.getInputStream();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		int formSize = request.getContentLength();

		DataInputStream dataInputStream = new DataInputStream(servletInputStream);
		byte[] b = new byte[formSize];
		byte t = 0;
		int i = 0;
		while (true) {
			try {
				t = dataInputStream.readByte();
			} catch (IOException e) {
				break;
			}
			b[i] = t;
			i++;
		}

		String stringData = "";

		try {
			stringData = new String(b, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
		while (stringData.indexOf(parameterSign) > 0) {
			int beginIndex = stringData.indexOf(parameterSign);
			stringData = stringData.substring(beginIndex + parameterSign.length());
			int endIndex = stringData.indexOf("\"");
			String parameterName = stringData.substring(0, endIndex);
			stringData = stringData.substring(parameterName.length() + 1);
			String parameterValue;
			String isFile;
			if (stringData.indexOf(fileSign) >= 0 && stringData.indexOf(fileSign) < stringData.indexOf("-")) {
				beginIndex = stringData.indexOf(fileSign);
				stringData = stringData.substring(beginIndex + 10);
				endIndex = stringData.indexOf("\"");
				String cFullName = stringData.substring(0, endIndex);
				beginIndex = cFullName.lastIndexOf("\\");
				parameterValue = cFullName.substring(beginIndex + 1);
				if (parameterValue != null && !parameterValue.equals("")) {
					int ss = (int)(Math.random()*100);
					parameterValue = commonUpfilePath + "/" + sessionId + ss + parameterValue;
				}
				isFile = "true";
			} else {
				endIndex = stringData.indexOf("-------");
				parameterValue = stringData.substring(4, endIndex - 2);
				isFile = "false";
			}
			Object[] obj = new Object[3];
			obj[0] = parameterName;
			obj[1] = parameterValue;
			obj[2] = isFile;
			list.add(obj);
		}
		
		try {
			stringData = new String(b, "ISO8859_1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}

		for (int index = 0; index < list.size(); index++) {
			Object[] obj = (Object[]) list.get(index);
			String parameterName = (String) obj[0];
			String parameterValue = (String) obj[1];
			map.put(parameterName, parameterValue);
			
			if (((String) obj[2]).equals("true")) {
				int beginIndex = stringData.indexOf("Content-Type:");
				stringData = stringData.substring(beginIndex);
				beginIndex = stringData.indexOf("\n");
				stringData  = stringData.substring(beginIndex + 3);
				
				if (parameterValue == null || parameterValue.equals("")) {
					continue;
				}

				String filePath = FileInfo.getFilePath(parameterValue);
				File file = new File(filePath);
				FileOutputStream fileOutputStream = null;
				try {
					file.getParentFile().mkdirs();
					file.createNewFile();
					fileOutputStream = new FileOutputStream(file);
				} catch (IOException e) {
					e.printStackTrace();
					return null;
				}

				int endIndex = stringData.indexOf("\n-----------------------------");
				String fileData = null;
				if (endIndex != -1) {
					fileData  = stringData.substring(0, endIndex - 1);
				}

				try {
					byte[] img = fileData.getBytes("ISO8859_1");
					for (i = 0; i < img.length; i++) {
						fileOutputStream.write(img[i]);
					}
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
					return null;
				}				
			}
		}

		return map;
	}
}